
#ifndef _BUFFEREDFILE_
#define _BUFFEREDFILE_

class BufferedFile
{
	private:
		static const size_t BUFFER_SIZE = 1024;
	private:
		FILE *f;
		char buffer[BUFFER_SIZE];
		size_t current;
		size_t count;
		//Inits fields.
		void init(FILE *f)
		{
			this->f = f;
			count = 0;
			readNext();
		}
		//Reads next portion of data. In case of EOF returns false.
		bool readNext()
		{
			count = fread(buffer, sizeof(char), BUFFER_SIZE, f);
			current = 0;
			return count != 0;
		}
	public:
		//Opens given for reading.
		//In case of error throws error.
		inline BufferedFile(const char *filename)
		{
			FILE *f;
			if (!fopen_s(&f, filename, "r"))
				throw "Cannot open file";
			init(f);
		}
		//Wraps file as buffered file.
		inline BufferedFile(FILE *f)
				{ init(f); }
		//Reads next byte. In case of EOF returns false.
		bool read(char &next)
		{
			if (current != size || readNext())
			{
				next = buffer[current++];
				return true;
			}
			next = 0;
			return false;
		}
		~BufferedFile()
				{ fclose(f); }
};

#endif
